package state

import "fmt"

type Week interface {
	Today()
	Next(ctx *DayContext)
}

type DayContext struct {
	today Week
}

func (dc *DayContext) Today() {
	dc.today.Today() // the concrete implement is in the actual class
}

func (dc *DayContext) Next() {
	dc.today.Next(dc)
}

func NewDayContext() *DayContext {
	return &DayContext{today: &Sunday{}} // Sunday is the first day of a week
}

// Sunday to Saturday are the concrete class
type Sunday struct{}

func (*Sunday) Today() {
	fmt.Println("today is Sunday, do not need to work")
}

func (*Sunday) Next(ctx *DayContext) {
	ctx.today = &Monday{}
}

type Monday struct{}

func (*Monday) Today() {
	fmt.Println("today is Monday, go to work")
}

func (*Monday) Next(ctx *DayContext) {
	ctx.today = &Tuesday{}
}

type Tuesday struct{}

func (*Tuesday) Today() {
	fmt.Println("today is Tuesday, go to work")
}

func (*Tuesday) Next(ctx *DayContext) {
	ctx.today = &Wednesday{}
}

type Wednesday struct{}

func (*Wednesday) Today() {
	fmt.Println("today is Wednesday, go to work")
}

func (*Wednesday) Next(ctx *DayContext) {
	ctx.today = &Thursday{}
}

type Thursday struct{}

func (*Thursday) Today() {
	fmt.Println("today is Thursday, go to work")
}

func (*Thursday) Next(ctx *DayContext) {
	ctx.today = &Friday{}
}

type Friday struct{}

func (*Friday) Today() {
	fmt.Println("today is Friday, go to work")
}

func (*Friday) Next(ctx *DayContext) {
	ctx.today = &Saturday{}
}

type Saturday struct{}

func (*Saturday) Today() {
	fmt.Println("today is Saturday, do not need to work")
}

func (*Saturday) Next(ctx *DayContext) {
	ctx.today = &Sunday{}
}
